﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Antlr.Runtime;
using Antlr.Runtime.Tree;
using SwimmingCompetition.Visitors;
using SwimmingCompetition.Exceptions;

namespace SwimmingCompetition
{
    public partial class EditorForm : Form
    {
        private CommonTree tree;
        SwimmingCompetitionGrammarParser.s_return _r;

        public EditorForm()
        {
            InitializeComponent();
        }

        private void buttonClear_Click(object sender, EventArgs e)
        {
            _richTextBoxEditor.Text = "";
            _richTextBoxConsole.Text += "\nLanguage Phrase editor cleared.\n\n";
            ScrollTextBox(_richTextBoxConsole);
            ScrollTextBox(_richTextBoxEditor);
        }

        private void _buttonOpen_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                ofd.Filter = "Grammar files (*.g)|*.g|Tutti i file (*.*)|*.*";
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    _richTextBoxEditor.Text = "";
                    StreamReader objReader = new StreamReader(ofd.FileName);
                    _richTextBoxEditor.Text = objReader.ReadToEnd();
                    _richTextBoxConsole.Text += "Opened file: \"" + ofd.FileName +"\".\n";
                    objReader.Close();
                    ScrollTextBox(_richTextBoxConsole);
                    ScrollTextBox(_richTextBoxEditor);
                }
            }
        }

        private void _buttonSave_Click(object sender, EventArgs e)
        {
            using (SaveFileDialog sfd = new SaveFileDialog())
            {
                sfd.Filter = "Grammar files (*.g)|*.g|Tutti i file (*.*)|*.*";
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    StreamWriter objWriter = new StreamWriter(sfd.FileName);
                    objWriter.Write(_richTextBoxEditor.Text);
                    objWriter.Flush();
                    objWriter.Close();
                    _richTextBoxConsole.Text += "Saved file: \"" + sfd.FileName + "\".\n";
                    ScrollTextBox(_richTextBoxConsole);
                    ScrollTextBox(_richTextBoxEditor);
                }
            }
        }

        private void _buttonValidate_Click(object sender, EventArgs e)
        {
            StreamWriter objWriter = new StreamWriter("Grammar.g",false);
            objWriter.Write(_richTextBoxEditor.Text);
            objWriter.Flush();
            objWriter.Close();
            try
            {
                ICharStream stream = new ANTLRFileStream("Grammar.g");
                SwimmingCompetitionGrammarLexer lexer = new SwimmingCompetitionGrammarLexer(stream);
                CommonTokenStream tokens = new CommonTokenStream(lexer);
                SwimmingCompetitionGrammarParser parser = new SwimmingCompetitionGrammarParser(tokens);
                _r = parser.s();

                if (_r.Tree != null)
                {
                    tree = (CommonTree)_r.Tree;
                    _richTextBoxConsole.Text += "\n" + ((CommonTree)_r.Tree).ToStringTree() + "\n\n";
                    ((CommonTree)_r.Tree).SanityCheckParentAndChildIndexes();
                }
                ScrollTextBox(_richTextBoxConsole);
                ScrollTextBox(_richTextBoxEditor);
                buttonHTML.Enabled = true;
                buttonTreeView.Enabled = true;
                generateToolStripMenuItem.Enabled = true;
            }
            catch (ErrorNodeException ex)
            {
                _richTextBoxConsole.Text += "\nParse Error at "+ex.ErrorMessage+".\n";
                ScrollTextBox(_richTextBoxConsole);
            }
        }

        private void ScrollTextBox(RichTextBox box)
        {
            box.SelectionLength = 0;
            box.SelectionStart = box.TextLength;
            box.ScrollToCaret();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Progetto di Linguaggi e Modelli computazionali M\nProf. Enrico Denti\nRealizzato da Isabella Gottardi", "Swimming Event Generator", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void hTMLToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                IEventVisitor visitor = new HTMLVisitor("");
                visitor.Visit((AST.EventNode)_r.Tree);
                _richTextBoxConsole.Text += "\nHTML generated.\n";
                ScrollTextBox(_richTextBoxConsole);
            }
            catch (ACodeException ex)
            {
                MessageBox.Show(ex.ErrorMessage);
                _richTextBoxConsole.Text += "\nHTML not generated, ACodeException.\n";
                ScrollTextBox(_richTextBoxConsole);
            }
            catch (LaneOutOfBoundException ex)
            {
                MessageBox.Show(ex.ErrorMessage);
                _richTextBoxConsole.Text += "\nHTML not generated, LaneOutOfBoundException.\n";
                ScrollTextBox(_richTextBoxConsole);
            }
            catch (TimeOutOfBoundsException ex)
            {
                MessageBox.Show(ex.ErrorMessage);
                _richTextBoxConsole.Text += "\nHTML not generated, TimeOutOfBoundsException.\n";
                ScrollTextBox(_richTextBoxConsole);
            }
            catch (ATimeException ex)
            {
                MessageBox.Show(ex.ErrorMessage);
                _richTextBoxConsole.Text += "\nHTML not generated, AtimeException.\n";
                ScrollTextBox(_richTextBoxConsole);
            }
        }

        private void useWizardToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _richTextBoxEditor.Text = "";
            EventWizard wiz = new EventWizard();
            wiz.ShowDialog();
            _richTextBoxConsole.Text += "\nLanguage Phrase loaded with wizard.\n";
            _richTextBoxEditor.Text += wiz.Grammar;
            ScrollTextBox(_richTextBoxConsole);
            ScrollTextBox(_richTextBoxEditor);
        }

        private void _treeViewEditorHelp_DoubleClick(object sender, EventArgs e)
        {
            if (_treeViewEditorHelp.SelectedNode != null)
            {
                _richTextBoxEditor.Text += _treeViewEditorHelp.SelectedNode.Name;
                _richTextBoxConsole.Text += "Added \"" + _treeViewEditorHelp.SelectedNode.Name + "\".\n";
                ScrollTextBox(_richTextBoxConsole);
                ScrollTextBox(_richTextBoxEditor);
            }
        }

        private void buttonTreeView_Click(object sender, EventArgs e)
        {
            try
            {
                IEventVisitor visitor = new TreeBuilderVisitor();
                visitor.Visit((AST.EventNode)_r.Tree);
                _richTextBoxConsole.Text += "\nTree generated.\n";
                ScrollTextBox(_richTextBoxConsole);
            }
            catch (ACodeException ex)
            {
                MessageBox.Show(ex.ErrorMessage);
                _richTextBoxConsole.Text += "\nTree not generated, ACodeException.\n";
                ScrollTextBox(_richTextBoxConsole);
            }
            catch (LaneOutOfBoundException ex)
            {
                MessageBox.Show(ex.ErrorMessage);
                _richTextBoxConsole.Text += "\nTree not generated, LaneOutOfBoundException.\n";
                ScrollTextBox(_richTextBoxConsole);
            }
            catch (TimeOutOfBoundsException ex)
            {
                MessageBox.Show(ex.ErrorMessage);
                _richTextBoxConsole.Text += "\nTree not generated, TimeOutOfBoundsException.\n";
                ScrollTextBox(_richTextBoxConsole);
            }
            catch (ATimeException ex)
            {
                MessageBox.Show(ex.ErrorMessage);
                _richTextBoxConsole.Text += "\nTree not generated, AtimeException.\n";
                ScrollTextBox(_richTextBoxConsole);
            }
        }
    }
}
